package campus.aiit.ssl.service;

import campus.aiit.ssl.dao.CollectLogDao;
import campus.aiit.ssl.dao.DeviceDao;
import campus.aiit.ssl.dao.MessageDao;
import campus.aiit.ssl.domain.model.*;
import campus.aiit.ssl.manage.custom.dao.DaoProxy;
import campus.aiit.ssl.manage.modbus.ModBus;
import campus.aiit.ssl.manage.modbus.ModBusCommand;
import campus.aiit.ssl.manage.modbus.SocketForModBus;
import campus.aiit.ssl.util.Factory.MessageFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class LogService {

    private static final Lock lock = new ReentrantLock();

    private ModBusCommand cmd;
    private DeviceDao deviceDao;
    private CollectLogDao collectLogDao;
    private MessageDao messageDao;
    private LocationService locationService;
    private Long day;
    private SimpleDateFormat df = new SimpleDateFormat("yy-MM-dd HH:mm:ss");
    private MessageFactory messageFactory;

    public LogService(ModBusCommand cmd, DeviceDao deviceDao, CollectLogDao collectLogDao, LocationService locationService, MessageDao messageDao,
                      MessageFactory messageFactory) {
        this.cmd = cmd;
        this.deviceDao = new DaoProxy<DeviceDao>().getProxy(deviceDao);
        this.collectLogDao = collectLogDao;
        this.locationService = locationService;
        this.messageDao = messageDao;
        this.messageFactory = messageFactory;
    }

//  public void writeDeviceLog(){
//    List<Device> list = deviceDao.selectByUserId(null);
//    list.forEach(device -> {
//      CollectLog collectLog = new CollectLog();
//      collectLog.setDeviceId(device.getId());
//      collectLog.setContextT(35);
//      collectLog.setAmperes(800);
//
//      Message message = messageFactory.getMessage(collectLog);
//      Message modifyMessage = messageDao.selectByDASC(collectLog.getDeviceId(),message.getAlarmId(),message.getStatus());
//      if(modifyMessage!=null){
//        System.out.println("存在消息未读");
//          try{
//              long date1 = df.parse(df.format(new Date())).getTime();
//              long date2 = df.parse(df.format(modifyMessage.getCreateTime())).getTime();
//              if ((date1-date2)/(1000*60*60)>=1){
//                  System.out.println("存在消息未读且间隔时间大于1小时");
//                  message.setId(modifyMessage.getId());
//                  message.setCreateTime(df.parse(df.format(new Date())));
//                  messageDao.updateByPrimaryKeySelective(message);
//              }
//          } catch (ParseException e) {
//              e.printStackTrace();
//          }
//      } else {
//          messageDao.insertSelective(message);
//      }
//    });
//  }

//  public void writeDeviceLogTransient(){
//
//    List<Device> list = deviceDao.selectByUserId(null);
//    SocketForModBus.SDU sdu = new SocketForModBus.SDU();
//    list.forEach(device -> {
//      CollectLog collectLog = new CollectLog();
//      collectLog.setDeviceId(device.getId());
//      // build SDU(header)
//      sdu.setHost(device.getIpAddress());
//      sdu.setPort(device.getPort());
//      ModBus.ADU adu = new ModBus.ADU();
//      adu.setAddress(device.getAddressCode());
//      sdu.setAdu(adu);
//      // perform cmd
//     // collectLog.setAutoStatus((byte) (cmd.autoStatus(sdu) ? 1 : 0));
//      collectLog.setRelayStatus((byte) (cmd.relayStatus(sdu) ? 1 : 0));
//      collectLog.setOnOffStatus((byte) (cmd.onOffStatus(sdu) ? 1 : 0));
//    //  collectLog.setBuzzerStatus((byte) (cmd.buzzerStatus(sdu) ? 1 : 0));
//      collectLog.setZigbeeStatus(cmd.zigbeeStatus(sdu));
//      collectLog.setZigbeeStatusFs(cmd.zigbeeStatusFs(sdu));
//    //  collectLog.setMode((byte) (cmd.mode(sdu) ? 1 : 0));
//
//      collectLog.setContextT(cmd.temperature(sdu));
//     // collectLog.setElectricConsume(cmd.electricConsume(sdu));
//   //   collectLog.setVolts(cmd.volts(sdu));
//      collectLog.setAmperes(cmd.amperes(sdu));
//
//      collectLogDao.insertSelective(collectLog);
//
//      Message message = messageFactory.getMessage(collectLog);
//      Message modifyMessage = messageDao.selectByDASC(collectLog.getDeviceId(),message.getAlarmId(),message.getStatus());
//      if(modifyMessage!=null){
//        System.out.println("存在消息未读");
//        try{
//          long date1 = df.parse(df.format(new Date())).getTime();
//          long date2 = df.parse(df.format(modifyMessage.getCreateTime())).getTime();
//          if ((date1-date2)/(1000*60*60)>=1){
//            System.out.println("存在消息未读且间隔时间大于1小时");
//            message.setId(modifyMessage.getId());
//            message.setCreateTime(df.parse(df.format(new Date())));
//            messageDao.updateByPrimaryKeySelective(message);
//          }
//        } catch (ParseException e) {
//          e.printStackTrace();
//        }
//      } else {
//        messageDao.insertSelective(message);
//      }
//    });
//  }

    public void writeDeviceLog() {
        // 加同步锁防止定时任务和rest接口冲突造成报文读取混乱
        if (lock.tryLock()) {
            try {
                List<Device> list = deviceDao.selectByUserId(null);
                SocketForModBus.SDU sdu = new SocketForModBus.SDU();
                list.forEach(device -> {
                    CollectLog collectLog = new CollectLog();
                    collectLog.setDeviceId(device.getId());
                    // build SDU(header)
                    sdu.setHost(device.getIpAddress());
                    sdu.setPort(device.getPort());
                    ModBus.ADU adu = new ModBus.ADU();
                    adu.setAddress(device.getAddressCode());
                    sdu.setAdu(adu);
                    // perform cmd
                    collectLog.setAutoStatus((byte) (cmd.autoStatus(sdu) ? 1 : 0));
                    collectLog.setRelayStatus((byte) (cmd.relayStatus(sdu) ? 1 : 0));
                    collectLog.setOnOffStatus((byte) (cmd.onOffStatus(sdu) ? 1 : 0));
                    collectLog.setBuzzerStatus((byte) (cmd.buzzerStatus(sdu) ? 1 : 0));
                    collectLog.setZigbeeStatus(cmd.zigbeeStatus(sdu));
                    collectLog.setZigbeeStatusFs(cmd.zigbeeStatusFs(sdu));
                    collectLog.setMode((byte) (cmd.mode(sdu) ? 1 : 0));

                    collectLog.setContextT(cmd.temperature(sdu));
                    collectLog.setElectricConsume(cmd.electricConsume(sdu));
                    int volts = cmd.volts(sdu);
                    collectLog.setVolts(volts);
                    collectLog.setAmperes(cmd.amperes(sdu));

                    System.out.println("电流"+collectLog.getAmperes());

                    System.out.println("电压：" + volts);
                    // TODO 暂时放开电压判断
//                    if (volts != 0) {
//
//                    }
                    collectLogDao.insertSelective(collectLog);
                    Message message = messageFactory.getMessage(collectLog);
                    Message modifyMessage = messageDao.selectByDASC(collectLog.getDeviceId(), message.getAlarmId(), message.getStatus());
                    if (modifyMessage != null) {
                        System.out.println("存在消息未读");
                        try {
                            long date1 = df.parse(df.format(new Date())).getTime();
                            long date2 = df.parse(df.format(modifyMessage.getCreateTime())).getTime();
                            if ((date1 - date2) / (1000 * 60 * 60) >= 1) {
                                System.out.println("存在消息未读且间隔时间大于1小时");
                                message.setId(modifyMessage.getId());
                                message.setCreateTime(df.parse(df.format(new Date())));
                                messageDao.updateByPrimaryKeySelective(message);
                            }
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                    } else {
                        messageDao.insertSelective(message);
                    }
                });
            } catch (Exception e) {
                System.err.println("错误栈定位于writeDeviceLog方法" + e.getMessage());
            } finally {
                lock.unlock();
            }
        }else {
            System.out.println("writeLog skipped due to lock.");
        }
    }

    public void deleteDeviceLog() {
        day = locationService.globalConfig()[0].getDataClean();
        System.out.println(locationService.deleteByTime(day));
    }

    public void addElectricConsumeLog() {
        collectLogDao.addElectricConsumeLog();
    }
}